/*    
 * THis file is part of the xoperator SPARQL/XMPP agent.
 * For further information see: http://xoperator.sf.net
 * Copyright (C) 2007  Jörg Unbehauen  

 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 */
package net.sf.xoperator.rdfxmpp;

import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.input.DOMBuilder;
import org.jdom.output.XMLOutputter;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.util.StringUtils;
import org.openbbs.blackboard.ks.KSExecutionContext;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.dom2_builder.DOM2XmlPullBuilder;

import net.sf.xoperator.Constants;
import net.sf.xoperator.ui.trans.TransformedResult;

public class SPARQLResult extends IQ {
	
//	private String query;

	private String result;

	private String storeName;
	
	private boolean sent;
	
	public void setSent(boolean sent) {
		this.sent = sent;
	}
	
	public boolean isSent() {
		return sent;
	}
	

	public String getResult() {
		return this.result;
	}

	public String getStoreName() {
		return this.storeName;
	}
	
	public void setStoreName(String storeName) {
		this.storeName = storeName;
	}

	public SPARQLResult(String result, String storeName) {
		super();
		this.result = result;
		this.storeName = storeName;
		this.setType(IQ.Type.RESULT);
	}
	
	@Override
	public String getChildElementXML() {
		StringBuffer buffer = new StringBuffer();
		buffer.append("<sparql-result xmlns=\"");
		buffer.append(Constants.SPARQL_XMPP_SPEC_URL);
		buffer.append("\">");
		buffer.append("<meta>");
		buffer.append("<storename>");
		buffer.append(storeName);
		buffer.append("</storename>");
//		buffer.append("<query>");
//		buffer.append(query);
//		buffer.append("</query>");
		buffer.append("</meta>");
		buffer.append(clearResult(result));
		
		buffer.append("</sparql-result>");

		return buffer.toString();
	}
	
	
	private static String clearResult(String result){
		return result.substring(result.indexOf("<sparql"));
	}
	
//	public String getQuery() {
//		return query;
//	}
//	
//	public void setQuery(String query) {
//		this.query = query;
//	}
	
	
	public static class Provider implements IQProvider{
		
		private Log log = LogFactory.getLog(SPARQLResult.Provider.class);

		public IQ parseIQ(XmlPullParser xpp) throws Exception {
			String meta = "";
			String result = "";
			
			Element ele = new DOMBuilder().build(new DOM2XmlPullBuilder().parseSubTree(xpp));
			
			//String theWholeThing = new XMLOutputter().outputString(ele);
			Namespace ns = Namespace.getNamespace(Constants.SPARQL_XMPP_SPEC_URL);
			
			//if(ele.getChild("meta",ns)!=null&&ele.getChild("meta").getChild("storename")!=null){
			meta = ele.getChild("meta",ns).getChild("storename",ns).getText();
			//
			result = new XMLOutputter().outputString(ele.getChild("sparql",Constants.HTTP_WWW_W3_ORG_2005_SPARQL_RESULTS));
			

			return new SPARQLResult(result,meta);
		}
	}
	
		
	
	public static class IQPacketFilter implements PacketFilter{
		public boolean accept(Packet arg0) {
			return arg0 instanceof SPARQLResult;
		}
	}
	
	public static class IQPacketListener implements PacketListener{
		
		private Map<String, KSExecutionContext> queryContextMapping = new ConcurrentHashMap<String, KSExecutionContext>();
		
		private Log log = LogFactory.getLog(SPARQLResult.IQPacketListener.class);
		
		public void processPacket(Packet arg0) {
			SPARQLResult result = (SPARQLResult) arg0;
			//hoohooo dodgy
			log.info("received result: "+ result.getPacketID()+" " + result.getResult());
			
			queryContextMapping.get(result.getPacketID()).blackboard().write(result);

				

			
		}
		
		public void registerQuery(SPARQLQuery query, KSExecutionContext context){
			queryContextMapping.put(query.getPacketID(), context);
			
		}
	}
	
	
	
	
	

	
	

}
